package com.block.channel.service.monitor;

import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.http.HttpUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.block.channel.enums.MonitorChannelEnum;
import com.block.channel.model.dto.MonitorInfoDTO;
import com.block.channel.model.result.CallbackResult;
import com.block.channel.service.IChannelCallbackService;
import com.block.channel.service.IChannelMonitorService;
import com.block.common.constant.RedisKeyConstant;
import com.block.common.service.LogFactory;
import com.block.common.util.LocalDateUtil;
import com.block.db.entity.ChannelBaseInfo;
import com.block.db.entity.SystemConstantInfo;
import com.block.db.mapper.SystemConstantInfoMapper;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;
import org.slf4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.io.IOException;
import java.security.MessageDigest;
import java.sql.Struct;
import java.time.LocalDateTime;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;

/**
 * http://127.0.0.1:1779/apinotice/channel/notifyResult/vivo/vivo?OS=0&IMEI=F1C7976BC455CB548BFC550EB7687F06&OAID=B8CE8A9A45816ADCD30950B39189B304&UA=Mozilla%2F5.0(Linux%3BAndroid4.0.4%3BGTI9220%20Build%2FIMM76D)&TS=119862898410
 *
 * https://www.xxxxx.com.cn/clk?OS=0&IMEI=F1C7976BC455CB548BFC550EB7687F06&OAID=B8CE8A9A45816ADCD30950B39189B304&UA=Mozilla%2F5.0(Linux%3BAndroid4.0.4%3BGTI9220%20Build%2FIMM76D)&TS=119862898410
 * https://api.koukoudai.shop?&actionType=CLICK&OS=_OS_&IMEI=_IMEI_&OAID=_OAID_&UA=_UA_&TS=_TS_&MAC=_MAC_&ANDROIDID=_ANDROIDID_&REQUESTID=_REQUESTID_&CAMPAIGNID=_CAMPAIGNID_&ADNAME=_ADNAME_&CREATIVEID=_CREATIVEID_
 * https://api.koukoudai.shop?&actionType=EXPOSE&OS=_OS_&IMEI=_IMEI_&OAID=_OAID_&UA=_UA_&TS=_TS_&MAC=_MAC_&ANDROIDID=_ANDROIDID_&REQUESTID=_REQUESTID_&CAMPAIGNID=_CAMPAIGNID_&ADNAME=_ADNAME_&CREATIVEID=_CREATIVEID_
 */
@Service
public class VivoMonitorService implements IChannelMonitorService, IChannelCallbackService {

    private static Logger log = LogFactory.getCommLog();

    public static String CODE_VIVO_TOKEN = "VIVO_TOKEN_CODE";
    public static String CODE_VIVO_REFRESH_TOKEN = "VIVO_REFRESH_TOKEN_CODE";

    public static String CLIENT_ID = "20240716015";
    public static String CLIENT_SECRET = "0B2D456B8935921DF64701D8674CC1D7DE6B893C3F1A67832DC374521882B02E";

    @Resource
    SystemConstantInfoMapper systemConstantInfoMapper;
    @Autowired
    StringRedisTemplate stringRedisTemplate;

    @Override
    public MonitorInfoDTO handleRequestParam(ChannelBaseInfo channelBaseInfo, String actionType, Map<String, String[]> parameterMap, String paramContent) {

        MonitorInfoDTO monitorInfoDTO = new MonitorInfoDTO();

        monitorInfoDTO.setPlatform(MonitorChannelEnum.VIVO.getValue());
        monitorInfoDTO.setChannelCode(channelBaseInfo.getChannelCode());
        monitorInfoDTO.setChannelName(channelBaseInfo.getChannelName());
        monitorInfoDTO.setMonitorInfo(JSON.toJSONString(parameterMap));

        String[] uniqueIdArr = parameterMap.get("OAID");
        String[] IMEIArr = parameterMap.get("IMEI");
        String[] REQUESTIDArr = parameterMap.get("REQUESTID");
        String[] CREATIVEIDArr = parameterMap.get("CREATIVEID");

        if (ObjectUtil.isNotEmpty(uniqueIdArr)){
            monitorInfoDTO.setUniqueKey(uniqueIdArr[0]);
            monitorInfoDTO.setKeyType("OAID");
        }
//        else{
//            monitorInfoDTO.setUniqueKey(IMEIArr[0]);
//            monitorInfoDTO.setKeyType("IMEI");
//        }

        JSONObject callbackObject = new JSONObject();
        if (ObjectUtil.isNotEmpty(REQUESTIDArr)){
            callbackObject.put("requestId",REQUESTIDArr[0]);
        }
        if (ObjectUtil.isNotEmpty(CREATIVEIDArr)){
            callbackObject.put("creativeId",CREATIVEIDArr[0]);
        }

        monitorInfoDTO.setCallbackInfo(JSON.toJSONString(callbackObject));

        monitorInfoDTO.setActionType(actionType);

        return monitorInfoDTO;
    }

    @Override
    public CallbackResult handleCallback(ChannelBaseInfo channelBaseInfo, String function, Map<String, String[]> parameterMap, String paramContent) {

        if (StrUtil.equals("authcode", function)){
            /**
             * 处理授权码
             */
            String[] codeArr = parameterMap.get("code");
            String[] stateArr = parameterMap.get("state");
            String[] clientIdArr = parameterMap.get("clientId");

            // 请求accessToken, 根据authCode
            handleVivoAuthCode(codeArr[0]);

        }
        return null;
    }

    /**
     * 获取到 authCode 之后，请求accessToken
     * @param authCode
     */
    public void handleVivoAuthCode(String authCode){

        String getAccessTokenUrl = "https://marketing-api.vivo.com.cn/openapi/v1/oauth2/token?client_id={}&client_secret={}&grant_type=code&code={}";
        String requestUrl = StrUtil.format(getAccessTokenUrl, CLIENT_ID, CLIENT_SECRET, authCode);

        log.info("【VIVO请求TOKEN】【requestUrl】{} ", requestUrl);
        String result = HttpUtil.createGet(requestUrl)
                .execute()
                .body();

        // 保存token信息
        saveTokenInfo(result, "GET_ACCESS_TOKEN");

    }


    /**
     * 根据refresh 刷新token 信息
     * 查询token
     */
//    public void handleVivoRefreshToken(){
//
//        // 查询token 信息
//        SystemConstantInfo tokenInfo = systemConstantInfoMapper.getEntityByCode(CODE_VIVO_TOKEN);
//        LocalDateTime tokenInfoExpireTime = tokenInfo.getExpireTime();
//        // 如果token 不为空，且不超时的话，直接返回；否则，进行更新
//        if (ObjectUtil.isNotEmpty(tokenInfo) && LocalDateTime.now().isBefore(tokenInfoExpireTime)){
//            // 不为空，且没有超时
//            return;
//        }
//
//        // 查询refreshToken 信息
//        SystemConstantInfo refreshTokenInfo = systemConstantInfoMapper.getEntityByCode(CODE_VIVO_REFRESH_TOKEN);
//        // 如果为空，或者超时，则需要重新进行授权
//        if (ObjectUtil.isNotEmpty(tokenInfo) || LocalDateTime.now().isAfter(refreshTokenInfo.getExpireTime())){
//            //
//            return;
//        }
//
//        // 获取accessToken
//        String getRefreshTokenUrl = "https://marketing-api.vivo.com.cn/openapi/v1/oauth2/refreshToken?client_id={}&client_secret={}&refresh_token={}";
//        String requestUrl = StrUtil.format(getRefreshTokenUrl, CLIENT_ID, CLIENT_SECRET, refreshTokenInfo.getContentInfo());
//
//        String result = HttpUtil.createGet(requestUrl)
//                .execute()
//                .body();
//
//        // 保存 token 信息
//        saveTokenInfo(result, "REFRESH_TOKEN");
//
//    }

    /**
     * 根据请求返回信息，保存更新 token 相关信息
     * @param result
     */
    public void saveTokenInfo(String result, String actionType){

        log.info("【VIVO_TOEKN】保存token请求结果【actionType】{}【result】{}", actionType, result);

        JSONObject jsonObject = JSON.parseObject(result);
        Integer code = jsonObject.getInteger("code");
        String message = jsonObject.getString("message");
        if (!ObjectUtil.equals(0, code)){
            String msg = StrUtil.format("accessToken 返回信息不成功【code】{}【message】{}【actionType】{}", code, message, actionType);
            toManualAuth(msg);
            return ;
        }

        JSONObject data = jsonObject.getJSONObject("data");
        String access_token = data.getString("access_token");
        Long token_date = data.getLong("token_date");

        String refresh_token = data.getString("refresh_token");
        Long refresh_token_date = data.getLong("refresh_token_date");

        SystemConstantInfo tokenConstantInfo = systemConstantInfoMapper.getEntityByCode(CODE_VIVO_TOKEN);
        SystemConstantInfo updateToken = new SystemConstantInfo();
        updateToken.setContentInfo(access_token);

        LocalDateTime localDateTime = LocalDateUtil.getLongToLocalDateTime(token_date).minusDays(30);
        updateToken.setExpireTime(localDateTime);

        if (ObjectUtil.isEmpty(tokenConstantInfo)){
            // 需要新增
            updateToken.setType("VIVO_TOKEN");
            updateToken.setName("vivo 数据上报accessToken");
            updateToken.setCode(CODE_VIVO_TOKEN);
            systemConstantInfoMapper.insert(updateToken);
        }else{
            // 需要更新
            updateToken.setId(tokenConstantInfo.getId());
            systemConstantInfoMapper.updateById(updateToken);
        }

        // 更新 refresh token 常量信息
        SystemConstantInfo refreshTokenConstantInfo = systemConstantInfoMapper.getEntityByCode(CODE_VIVO_REFRESH_TOKEN);
        SystemConstantInfo updateRefreshToken = new SystemConstantInfo();
        updateRefreshToken.setContentInfo(refresh_token);

        LocalDateTime localDateTime1= LocalDateUtil.getLongToLocalDateTime(refresh_token_date).minusDays(30);
        updateRefreshToken.setExpireTime(localDateTime1);

        if (ObjectUtil.isEmpty(refreshTokenConstantInfo)){
            // 需要新增
            updateRefreshToken.setType("VIVO_TOKEN");
            updateRefreshToken.setName("vivo 数据上报refreshToken");
            updateRefreshToken.setCode(CODE_VIVO_REFRESH_TOKEN);
            systemConstantInfoMapper.insert(updateRefreshToken);
        }else{
            // 需要更新
            updateRefreshToken.setId(refreshTokenConstantInfo.getId());
            systemConstantInfoMapper.updateById(updateRefreshToken);
        }
    }

    /**
     *
     * 需要进行手动授权
     * 重新授权地址
     * https://open-ad.vivo.com.cn/OAuth?clientId=20240716015&state=恒盛融资担保（福州）有限公司&redirectUri=https://api.koukoudai.shop/apinotice/channel/callback/vivo/vivo/authcode
     */
    public void toManualAuth(String message){
        /**
         *
         */
        log.info("【VIVO_TOKEN】请求失败，需要重新授权【message】{}", message);

    }

}
